/**
 * 学习网址  http://react.css88.com/docs/state-and-lifecycle.html
 * 按照模块来学习react
 * 静态服务下运行
 * 想要运行哪个代码块 ， 加上 运行符 就OK
 * 建议VSCode打开
 */

// 入门
(function() {
    function formatName(user) {
        return user.firstName + " " + user.lastName;
    }
    const user = {
        firstName: "Harper",
        lastName: "Perez"
    };
    function getGreeting(user) {
        if (user) {
            return <h1 className="abc">Hello, {formatName(user)}!</h1>;
        }
        return <h1 className="abc">Hello, Stranger.</h1>;
    }
    const element = getGreeting(user);
    ReactDOM.render(element, document.getElementById("root"));
});

//更新
(function() {
    function tick() {
        const element = (
            <div>
                <h1>Hello, world!</h1>
                <h2>It is {new Date().toLocaleTimeString()}.</h2>
            </div>
        );
        ReactDOM.render(element, document.getElementById("root"));
    }

    setInterval(tick, 1000);
});
//组件
(function() {
    function Welcome(props) {
        return <h1>Hello, {props.name}</h1>;
    }

    class Welcome2 extends React.Component {
        render() {
            return <h1>Hello, {this.props.name}</h1>;
        }
    }
    const element = <Welcome name="Sara" />;
    const element2 = <Welcome2 name="Sara2" />;

    ReactDOM.render(element, document.getElementById("root"));
    setTimeout(() => {
        ReactDOM.render(element2, document.getElementById("root"));
    }, 3000);
});

//组合组件

(function() {
    function Welcome(props) {
        return <h1>Hello, {props.name}</h1>;
    }

    function App() {
        return (
            <div>
                <Welcome name="李四11" />
                <Welcome name="李四" />
                <Welcome name="王麻子" />
            </div>
        );
    }
    ReactDOM.render(<App />, document.getElementById("root"));
});

//提取组件
(function() {
    function Comment(props) {
        return (
            <div className="Comment">
                <UserInfo user={props.author} />
                <div className="Comment-text">{props.text}</div>
                <div className="Comment-date">{formatDate(props.date)}</div>
            </div>
        );
    }

    function Avatar(props) {
        return (
            <img
                className="Avatar"
                src={props.user.avatarUrl}
                alt={props.user.name}
            />
        );
    }

    function UserInfo(props) {
        return (
            <div className="UserInfo">
                <Avatar user={props.user} />
                <div className="UserInfo-name">{props.user.name}</div>
            </div>
        );
    }
});

//State & 生命周期
(function() {
    function tick() {
        const element = (
            <div>
                <h1>Hello, world!</h1>
                <h2>It is {new Date().toLocaleTimeString()}.</h2>
            </div>
        );
        ReactDOM.render(element, document.getElementById("root"));
    }

    setInterval(tick, 1000);
});

(function() {
    /*
    function Clock(props) {
        return (
            <div>
                <h1>Hello,world!</h1>
                <h2>It is {props.date.toLocaleTimeString()}.</h2>
            </div>
        );
    }

 */
    class Clock extends React.Component {
        constructor(props) {
            super(props);
            this.state = {
                date: new Date()
            };
        }
        componentDidMount() {
            console.log(this.props);
            this.timerID = setInterval(() => this.tick(), this.props.time);
        }
        componentWillUnmount() {
            clearInterval(this.timerID);
        }
        tick() {
            this.setState({ date: new Date() });
        }

        render() {
            return (
                <div>
                    <h1>Hello,world!</h1>
                    <h2>It is {this.state.date.toLocaleTimeString()}.</h2>
                </div>
            );
        }
    }

    class App extends React.Component {
        render() {
            return (
                <div>
                    <Clock time={1000} />
                    <Clock time={2000} />
                    <Clock time={5000} />
                </div>
            );
        }
    }

    function tick() {
        ReactDOM.render(<App />, document.getElementById("root"));
    }

    tick();
});
//处理事件
(function() {
    class Toggle extends React.Component {
        constructor(props) {
            super(props);
            this.state = {
                isToggleOn: true
            };
            // this.handleClick = this.handleClick.bind(this);
        }

        // handleClick() {     const _this = this;     _this.setState(state => ({
        // isToggleOn: !state.isToggleOn     })); }
        handleClick = () => {
            console.log(this);
            this.setState(state => ({
                isToggleOn: !state.isToggleOn
            }));
        };
        render() {
            return (
                <button onClick={this.handleClick}>
                    {this.state.isToggleOn ? "ON" : "OFF"}
                </button>
            );
        }
    }
    ReactDOM.render(<Toggle />, document.getElementById("root"));
});
//条件渲染
(function() {
    function UserGreeting(props) {
        return <h1>Welcome back!</h1>;
    }

    function GuestGreeting(props) {
        return <h1>Please sign up.</h1>;
    }
    function LoginButton(props) {
        return <button onClick={props.onClick}>Login</button>;
    }

    function LogoutButton(props) {
        return <button onClick={props.onClick}>Logout</button>;
    }
    function Greeting(props) {
        const isLoggedIn = props.isLoggedIn;
        if (isLoggedIn) {
            return <UserGreeting />;
        }
        return <GuestGreeting />;
    }
    class LoginControl extends React.Component {
        constructor(props) {
            super(props);
            this.handleLoginClick = this.handleLoginClick.bind(this);
            this.handleLogoutClick = this.handleLogoutClick.bind(this);
            this.state = {
                isLoggedIn: false
            };
        }

        handleLoginClick() {
            this.setState({ isLoggedIn: true });
        }

        handleLogoutClick() {
            this.setState({ isLoggedIn: false });
        }

        render() {
            const isLoggedIn = this.state.isLoggedIn;
            let button;

            if (isLoggedIn) {
                button = <LogoutButton onClick={this.handleLogoutClick} />;
            } else {
                button = <LoginButton onClick={this.handleLoginClick} />;
            }

            return (
                <div>
                    <Greeting isLoggedIn={isLoggedIn} /> {button}
                </div>
            );
        }
    }
    ReactDOM.render(<LoginControl />, document.getElementById("root"));
});

//列表(Lists) 和 键(Keys)
(function() {
    function NumberList(props) {
        const numbers = props.numbers;
        const listItems = numbers.map((e, i) => {
            return <li key={i}>{e}</li>;
        });
        return <ul>{listItems}</ul>;
    }

    const numbers = [1, 2, 3, 4, 5];

    ReactDOM.render(
        <NumberList numbers={numbers} />,
        document.getElementById("root")
    );
});
//表单(Forms)
(function() {
    // 表单提交动态列表 todoList
    class ShowText extends React.Component {
        render() {
            return <div>{this.props.text}</div>;
        }
    }
    class ShowTextList extends React.Component {
        constructor(props) {
            super(props);
            this.state = {
                textList: props.textList
            };
        }
        render() {
            const list = this.state.textList;
            let lis = [];
            for (let i = 0; i < list.length; i++) {
                const el = list[i];
                lis.push(<li key={i}>{el}</li>);
            }
            return <ul>{lis}</ul>;
        }
    }
    class NameForm extends React.Component {
        constructor(props) {
            super(props);
            this.state = {
                value: "",
                textList: []
            };
            // this.handleChange = this.handleChange.bind(this);
            // this.handleSubmit = this.handleSubmit.bind(this);
        }

        handleChange = event => {
            this.setState({ value: event.target.value });
        };

        handleSubmit = () => {
            const textList = this.state.textList;
            textList.push(this.state.value);
            this.setState((state, props) => {
                return {
                    textList,
                    value: ""
                };
            });
            event.preventDefault();
        };

        render() {
            return (
                <form onSubmit={this.handleSubmit}>
                    <label>
                        Name:
                        <input
                            type="text"
                            value={this.state.value}
                            onInput={this.handleChange}
                            onChange={this.handleChange}
                        />
                    </label>
                    <input type="submit" value="Submit" />
                    <ShowTextList textList={this.state.textList} />
                    <ShowText text={this.state.value} />
                </form>
            );
        }
    }

    ReactDOM.render(<NameForm />, document.getElementById("root"));
})();

(function() {
    // textarea  标签
    class EssayForm extends React.Component {
        constructor(props) {
            super(props);
            this.state = {
                value: "Please write an essay about your favorite DOM element."
            };

            this.handleChange = this.handleChange.bind(this);
            this.handleSubmit = this.handleSubmit.bind(this);
        }

        handleChange(event) {
            this.setState({ value: event.target.value });
        }

        handleSubmit(event) {
            alert("An essay was submitted: " + this.state.value);
            event.preventDefault();
        }

        render() {
            return (
                <form onSubmit={this.handleSubmit}>
                    <label>
                        Essay:
                        <textarea
                            value={this.state.value}
                            onChange={this.handleChange}
                        />
                    </label>
                    <input type="submit" value="Submit" />
                </form>
            );
        }
    }

    ReactDOM.render(<EssayForm />, document.getElementById("root"));
});

(function() {
    class FlavorForm extends React.Component {
        constructor(props) {
            super(props);
            this.state = { value: "coconut" };

            this.handleChange = this.handleChange.bind(this);
            this.handleSubmit = this.handleSubmit.bind(this);
        }

        handleChange(event) {
            this.setState({ value: event.target.value });
        }

        handleSubmit(event) {
            alert("Your favorite flavor is: " + this.state.value);
            event.preventDefault();
        }

        render() {
            return (
                <form onSubmit={this.handleSubmit}>
                    <label>
                        Pick your favorite flavor:
                        <select
                            value={this.state.value}
                            onChange={this.handleChange}
                        >
                            <option value="grapefruit">Grapefruit</option>
                            <option value="lime">Lime</option>
                            <option value="coconut">Coconut</option>
                            <option value="mango">Mango</option>
                        </select>
                    </label>
                    <input type="submit" value="Submit" />
                </form>
            );
        }
    }

    ReactDOM.render(<FlavorForm />, document.getElementById("root"));
});

(function() {
    //处理多个输入元素
    class Reservation extends React.Component {
        constructor(props) {
            super(props);
            this.state = {
                isGoing: true,
                numberOfGuests: 2
            };

            this.handleInputChange = this.handleInputChange.bind(this);
        }

        handleInputChange(event) {
            const target = event.target;
            const value =
                target.type === "checkbox" ? target.checked : target.value;
            const name = target.name;

            this.setState({
                [name]: value
            });
        }

        render() {
            return (
                <form>
                    <label>
                        Is going:
                        <input
                            name="isGoing"
                            type="checkbox"
                            checked={this.state.isGoing}
                            onChange={this.handleInputChange}
                        />
                    </label>
                    <br />
                    <label>
                        Number of guests:
                        <input
                            name="numberOfGuests"
                            type="number"
                            value={this.state.numberOfGuests}
                            onChange={this.handleInputChange}
                        />
                    </label>
                </form>
            );
        }
    }
    ReactDOM.render(<Reservation />, document.getElementById("root"));
});

(function() {
    //受控 Input 组件的 null 值
    ReactDOM.render(<input value="hi" />, document.getElementById("root"));

    setTimeout(function() {
        ReactDOM.render(
            <input value={null} />,
            document.getElementById("root")
        );
    }, 5000);
});

//状态提升(Lifting State Up)
(function() {
    const scaleNames = {
        c: "Celsius",
        f: "Fahrenheit"
    };

    function toCelsius(fahrenheit) {
        return ((fahrenheit - 32) * 5) / 9;
    }

    function toFahrenheit(celsius) {
        return (celsius * 9) / 5 + 32;
    }

    function tryConvert(temperature, convert) {
        const input = parseFloat(temperature);
        if (Number.isNaN(input)) {
            return "";
        }
        const output = convert(input);
        const rounded = Math.round(output * 1000) / 1000;
        return rounded.toString();
    }

    class TemperatureInput extends React.Component {
        constructor(props) {
            super(props);
            this.handleChange = this.handleChange.bind(this);
        }

        handleChange(e) {
            this.props.onTemperatureChange(e.target.value);
        }

        render() {
            const temperature = this.props.temperature;
            const scale = this.props.scale;
            return (
                <fieldset>
                    <legend>Enter temperature in {scaleNames[scale]}:</legend>
                    <input value={temperature} onChange={this.handleChange} />
                </fieldset>
            );
        }
    }

    function BoilingVerdict(props) {
        if (props.celsius >= 100) {
            return <p>The water would boil.</p>;
        }
        return <p>The water would not boil.</p>;
    }

    class Calculator extends React.Component {
        constructor(props) {
            super(props);
            this.handleCelsiusChange = this.handleCelsiusChange.bind(this);
            this.handleFahrenheitChange = this.handleFahrenheitChange.bind(
                this
            );
            this.state = { temperature: "", scale: "c" };
        }

        handleCelsiusChange(temperature) {
            this.setState({ scale: "c", temperature });
        }

        handleFahrenheitChange(temperature) {
            this.setState({ scale: "f", temperature });
        }

        render() {
            const scale = this.state.scale;

            const temperature = this.state.temperature;

            const celsius =
                scale === "f"
                    ? tryConvert(temperature, toCelsius)
                    : temperature;

            const fahrenheit =
                scale === "c"
                    ? tryConvert(temperature, toFahrenheit)
                    : temperature;

            return (
                <fieldset>
                    <TemperatureInput
                        scale="c"
                        temperature={celsius}
                        onTemperatureChange={this.handleCelsiusChange}
                    />
                    <TemperatureInput
                        scale="f"
                        temperature={fahrenheit}
                        onTemperatureChange={this.handleFahrenheitChange}
                    />
                    <BoilingVerdict celsius={parseFloat(celsius)} />
                </fieldset>
            );
        }
    }

    ReactDOM.render(<Calculator />, document.getElementById("root"));
});
//组合(Composition) VS 继承(Inheritance)
(function() {
    function FancyBorder(props) {
        return (
            <div className={"FancyBorder FancyBorder-" + props.color}>
                {props.children}
            </div>
        );
    }

    function WelcomeDialog() {
        return (
            <FancyBorder color="blue">
                <h1 className="Dialog-title">Welcome</h1>
                <p className="Dialog-message">
                    Thank you for visiting our spacecraft!
                </p>
            </FancyBorder>
        );
    }

    ReactDOM.render(<WelcomeDialog />, document.getElementById("root"));
});

(function() {
    function Contacts(props) {
        return <h1>1111111111</h1>;
    }
    function Chat(props) {
        return <h1>222222222</h1>;
    }
    function SplitPane(props) {
        return (
            <div className="SplitPane">
                <div className="SplitPane-left">{props.left}</div>
                <div className="SplitPane-right">{props.right}</div>
            </div>
        );
    }

    function App() {
        return <SplitPane left={<Contacts />} right={<Chat />} />;
    }

    ReactDOM.render(<App />, document.getElementById("root"));
});

(function() {
    //特例
    function FancyBorder(props) {
        return (
            <div className={"FancyBorder FancyBorder-" + props.color}>
                {props.children}
            </div>
        );
    }
    function Dialog(props) {
        return (
            <FancyBorder color="blue">
                <h1 className="Dialog-title">{props.title}</h1>
                <p className="Dialog-message">{props.message}</p>
            </FancyBorder>
        );
    }

    function WelcomeDialog() {
        return (
            <Dialog
                title="Welcome"
                message="Thank you for visiting our spacecraft!"
            />
        );
    }
    ReactDOM.render(<WelcomeDialog />, document.getElementById("root"));
});

(function() {
    //花式嵌套
    function FancyBorder(props) {
        return (
            <div className={"FancyBorder FancyBorder-" + props.color}>
                {props.children}
            </div>
        );
    }
    function Dialog(props) {
        return (
            <FancyBorder color="blue">
                <h1 className="Dialog-title">{props.title}</h1>
                <p className="Dialog-message">{props.message}</p>
                {props.children}
            </FancyBorder>
        );
    }

    class SignUpDialog extends React.Component {
        constructor(props) {
            super(props);
            this.handleChange = this.handleChange.bind(this);
            this.handleSignUp = this.handleSignUp.bind(this);
            this.state = { login: "" };
        }

        handleChange(e) {
            this.setState({ login: e.target.value });
        }

        handleSignUp() {
            alert(`Welcome aboard, ${this.state.login}!`);
        }

        render() {
            return (
                <Dialog
                    title="Mars Exploration Program"
                    message="How should we refer to you?"
                >
                    <input
                        value={this.state.login}
                        onChange={this.handleChange}
                    />
                    <button onClick={this.handleSignUp}>Sign Me Up!</button>
                </Dialog>
            );
        }
    }
    ReactDOM.render(<SignUpDialog />, document.getElementById("root"));
});


/*

历时5天，终于把react基础文档啃完,接下来可以投入到实际项目中去了
http://react.css88.com/docs/glossary.html

 */
